package cn.iocoder.yudao.framework.business;

import cn.iocoder.yudao.framework.business.basic.dao.repository.LockRedisRepository;
import cn.iocoder.yudao.framework.business.basic.dao.repository.ObjectRedisRepository;
import cn.iocoder.yudao.framework.business.basic.dao.repository.SerialNoRedisRepository;
import cn.iocoder.yudao.framework.business.basic.pojo.po.ShopScopeEntity;
import cn.iocoder.yudao.framework.business.basic.pojo.po.TableEntity;
import cn.iocoder.yudao.framework.business.basic.pojo.po.UserScopeEntity;
import cn.iocoder.yudao.framework.business.captcha.controller.LegacyCaptchaController;
import cn.iocoder.yudao.framework.business.captcha.service.LegacyCaptchaService;
import cn.iocoder.yudao.framework.business.captcha.service.LegacyCaptchaServiceImpl;
import cn.iocoder.yudao.framework.business.monitor.service.MonitorService;
import cn.iocoder.yudao.framework.business.sse.service.SseService;
import cn.iocoder.yudao.framework.business.sse.service.SseServiceImpl;
import cn.iocoder.yudao.framework.mybatis.core.handler.DefaultDBFieldHandler;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 自动配置
 *
 * @author 山野羡民（1032694760@qq.com）
 */
@AutoConfiguration
public class BusinessAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public ObjectRedisRepository objectRedisRepository() {
        return new ObjectRedisRepository();
    }

    @Bean
    @ConditionalOnMissingBean
    public SerialNoRedisRepository serialNoRedisRepository() {
        return new SerialNoRedisRepository();
    }

    @Bean
    @ConditionalOnMissingBean
    public LockRedisRepository lockRedisRepository() {
        return new LockRedisRepository();
    }

    @Bean
    @ConditionalOnMissingBean
    public MonitorService monitorService() {
        return new MonitorService();
    }

    @Bean
    @ConditionalOnMissingBean
    public SseService sseService() {
        return new SseServiceImpl();
    }

    @Bean
    @ConditionalOnMissingBean
    public LegacyCaptchaService legacyCaptchaService() {
        return new LegacyCaptchaServiceImpl();
    }

    @Bean
    @ConditionalOnMissingBean
    public LegacyCaptchaController legacyCaptchaController() {
        return new LegacyCaptchaController();
    }

    /**
     * @see cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration#defaultMetaObjectHandler()
     * @link <a href="https://baomidou.com/guides/auto-fill-field/#_top">自动填充字段</a>
     */
    @Primary
    @Bean
    @ConditionalOnClass(LoginUser.class)
    public MetaObjectHandler featureDBFieldHandler() {
        return new FeatureDBFieldHandler();
    }

    /**
     *  通用参数填充实现类 如果没有显式的对通用参数进行赋值，这里会对通用参数进行填充、赋值
     */
    private static class FeatureDBFieldHandler extends DefaultDBFieldHandler {

        @Override
        public void insertFill(MetaObject metaObject) {
            Long userId = SecurityFrameworkUtils.getLoginUserId();
            LocalDateTime current = LocalDateTime.now();
            if (metaObject.getOriginalObject() instanceof TableEntity tableEntity) {
                // 创建时间为空，则以当前时间为插入时间
                if (Objects.isNull(tableEntity.getCreateTime())) {
                    tableEntity.setCreateTime(current);
                }
                // 更新时间为空，则以当前时间为更新时间
                if (Objects.isNull(tableEntity.getUpdateTime())) {
                    tableEntity.setUpdateTime(current);
                }
                // 当前登录用户不为空，若创建人为空，则当前登录用户为创建人
                if (Objects.nonNull(userId) && Objects.isNull(tableEntity.getCreator())) {
                    tableEntity.setCreator(userId.toString());
                }
                // 当前登录用户不为空，若更新人为空，则当前登录用户为更新人
                if (Objects.nonNull(userId) && Objects.isNull(tableEntity.getUpdater())) {
                    tableEntity.setUpdater(userId.toString());
                }
            } else {
                super.insertFill(metaObject);
            }
            if (metaObject.getOriginalObject() instanceof UserScopeEntity tableEntity) {
                // 当前登录用户不为空，若用户编号为空，则当前登录用户为用户编号
                if (Objects.nonNull(userId) && Objects.isNull(tableEntity.getUserId())) {
                    tableEntity.setUserId(userId);
                }
            }
            if (metaObject.getOriginalObject() instanceof ShopScopeEntity tableEntity) {
                Long shopId = SecurityFrameworkUtils.getLoginUserLastShopId();
                // 当前登录商家的店铺不为空，若店铺编号为空，则当前登录商家的店铺为店铺编号
                if (Objects.nonNull(shopId) && Objects.isNull(tableEntity.getShopId())) {
                    tableEntity.setShopId(shopId);
                }
            }
        }

        @Override
        public void updateFill(MetaObject metaObject) {
            Long userId = SecurityFrameworkUtils.getLoginUserId();
            LocalDateTime current = LocalDateTime.now();
            if (metaObject.getOriginalObject() instanceof TableEntity tableEntity) {
                // 当前登录用户不为空，若用户编号为空，则当前登录用户为用户编号
                if (Objects.nonNull(userId) && Objects.isNull(tableEntity.getUpdater())) {
                    tableEntity.setUpdater(userId.toString());
                }
                // 更新时间为空，则以当前时间为更新时间
                if (Objects.isNull(tableEntity.getUpdateTime())) {
                    tableEntity.setUpdateTime(current);
                }
            } else {
                super.updateFill(metaObject);
            }
        }

    }

}
